using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace winsw
{
	public static class SigIntHelper
	{
		private delegate bool ConsoleCtrlDelegate(CtrlTypes CtrlType);

		private enum CtrlTypes : uint
		{
			CTRL_C_EVENT = 0u,
			CTRL_BREAK_EVENT = 1u,
			CTRL_CLOSE_EVENT = 2u,
			CTRL_LOGOFF_EVENT = 5u,
			CTRL_SHUTDOWN_EVENT = 6u
		}

		private const string KERNEL32 = "kernel32.dll";

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern bool AttachConsole(uint dwProcessId);

		[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
		private static extern bool FreeConsole();

		[DllImport("kernel32.dll")]
		private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);

		[DllImport("kernel32.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);

		public static bool SendSIGINTToProcess(Process process, TimeSpan shutdownTimeout)
		{
			if (AttachConsole((uint)process.Id))
			{
				SetConsoleCtrlHandler(null, Add: true);
				GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0u);
				process.WaitForExit((int)shutdownTimeout.TotalMilliseconds);
				return process.HasExited;
			}
			return false;
		}
	}
}
